import argparse
from core.split_regex import split_regex
from functools import reduce
import re
import os
from io import TextIOWrapper
from enum import Enum


class NovelParer:
    def __init__(self, file, pattern):
        self.file = file
        self.pattern = pattern

    def parse(self):
        print("parse the location at <" + self.file + ">")
        # parse(**self.__dict__)
        novel = Novel()
        paragraphs = split_regex(self.file, self.pattern)
        print(len(paragraphs))

        desc = paragraphs[0]
        desc_line = next(filter(lambda x: "作者" in x, desc.split("\n")[5:]), "")
        parts = re.split(r"\W|\u4f5c\u8005\uff1a", desc_line)
        f = filter(lambda x: x != "", parts)
        novel.setTitle(next(f, "无题"))
        novel.setAuthor(next(f, "匿名"))

        texts = paragraphs[1:]
        it = iter(texts)
        for name, content in zip(it, it):
            chapter = NovelChapter(name.strip(), content)
            novel.appendChapter(chapter)
        return novel


class NovelChapter:
    def __init__(self, name: str, content: str):
        self.name = name
        self.content = content

    def save(self, out: str = "", filename: str | None = None):
        location = os.path.join(
            out, filename if filename != None else f"{self.name}.txt"
        )
        print(f"saving chapter on {location}")
        with open(location, mode="w") as fo:
            fo.write(self.name)
            fo.write("\n\n")
            fo.write(self.content)
            fo.close()

    def stream(self, fo: TextIOWrapper):
        fo.write(self.name)
        fo.write("\n\n")
        fo.write(self.content)


class ExportMode(Enum):
    SEP = 1
    MERGE = 2


class Novel:
    def __init__(self):
        self.title = ""
        self.author = ""
        self.chapters = []

    def __str__(self) -> str:
        return f"《{self.title}》 作者 {self.author} 章节{len(self.chapters)} 字数{self.countWord()}"

    def setTitle(self, title: str):
        self.title = title

    def setAuthor(self, author: str):
        self.author = author

    def setIntro(self, intro: str):
        self.intro = intro

    def appendChapter(self, chapter: NovelChapter):
        self.chapters.append(chapter)

    def countWord(self):
        return reduce(lambda aggr, item: aggr + len(item.content), self.chapters, 0)

    def exportTxt(
        self,
        start: int = 0,
        num: int = 1,
        out: str = "",
        mode: ExportMode = ExportMode.MERGE,
    ):
        if mode == ExportMode.MERGE and num > 1:
            location = os.path.join(out, f"{self.title}@{start + 1}~{start + num}.txt")
            print(f"saving chapter on {location}")
            with open(location, mode="w") as fo:
                [c.stream(fo) for c in self.chapters[start : start + num]]
                fo.close()
        else:
            [c.save(out) for c in self.chapters[start : start + num]]


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("file")
    parser.add_argument("--pattern", required=True)
    args = parser.parse_args()
    novelParser = NovelParer(**vars(args))
    novel = novelParser.parse()
    print("parsed小说:\n", novel)
    # [c.save() for c in novel.chapters[0:4]]
    novel.exportTxt(0, 2)
